<?php

namespace app\controllers;

use app\Behaviors\CitiesBehavior;
use app\Behaviors\CustomBehavior;
use app\behaviors\MessageBehavior;
use app\behaviors\UserBehavior;
use app\events\UserEvent;
use app\forms\VenkiForm;
use app\modelFilter\BookAFilter;
use app\modelFilter\BookFilter;
use app\modelFilter\PurchaseOrdersFilter;
use app\models\Books;
use app\models\Cities;
use app\models\PurchaseOrder;
use app\models\User;
use app\resources\UserResource;
use app\services\CustomService;
use app\services\UserService;
use app\services\VenkiEventService;
use Yii;
use yii\base\ErrorException;
use yii\data\ActiveDataFilter;
use yii\data\ActiveDataProvider;
use yii\web\Controller;
use yii\web\Request;
use yii\web\Response;
use app\models\LoginForm;
use app\models\ContactForm;

class SiteController extends Controller
{

    // 控制器调用事件行为是必须的
    public function behaviors()
    {
        return [
            UserBehavior::class
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function actions()
    {
        return [
            'error'   => [
                'class' => 'yii\web\ErrorAction',
            ],
            'captcha' => [
                'class'           => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
            ],
        ];
    }

    /**
     * Displays homepage.
     * @return string
     */
    public function actionIndex()
    {
        return $this->render('index');
    }

    /**
     * Login action.
     * @return Response|string
     */
    public function actionLogin()
    {
        if (!Yii::$app->user->isGuest) {
            return $this->goHome();
        }

        $model = new LoginForm();
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
            return $this->goBack();
        }

        $model->password = '';
        return $this->render('login', [
            'model' => $model,
        ]);
    }

    /**
     * Logout action.
     * @return Response
     */
    public function actionLogout()
    {
        Yii::$app->user->logout();

        return $this->goHome();
    }

    /**
     * Displays contact page.
     * @return Response|string
     */
    public function actionContact()
    {
        $model = new ContactForm();
        if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) {
            Yii::$app->session->setFlash('contactFormSubmitted');

            return $this->refresh();
        }
        return $this->render('contact', [
            'model' => $model,
        ]);
    }

    /**
     * Displays about page.
     * @return string
     */
    public function actionAbout()
    {
        return $this->render('about');
    }

    public function actionSay($message = 'Hello')
    {
        return $this->render('say', ['message' => $message]);
    }

    public function actionEntry(): string
    {
        $model = new EntryForm();

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            // 验证 $model 收到的数据

            // 做些有意义的事 ...

            return $this->render('entry-confirm', ['model' => $model]);
        } else {
            // 无论是初始化显示还是数据验证错误
            return $this->render('entry', ['model' => $model]);
        }
    }

    // 开发代码流程测试：route->controller->forms->service->filter->repository->model->response
    // 事件行为使用demo
    public function actionEvent(Request $request): void
    {

//        $this->behaviors['user']->A();
//        $user = new User();
        // 触发事件方式1
//        $user->trigger(User::EVENT_NEW_USER);
//        $event          = new UserEvent('陈文超');
//        $event->message = '陈文小超';
        $params = $request->get();
        VenkiEventService::venkiEvent($params);

        // 调用方式2：
//        $this->trigger(UserEvent::USER_TEST_EVENT, new UserEvent($params));

        /*UserEvent::on(UserEvent::class, UserEvent::USER_TEST_EVENT, function () {
        }, []);*/
        // 触发事件方式2

//        UserEvent::trigger($this, UserEvent::EVENT_TEST_USER);
//        \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
        // 创建并触发一个消息事件
        // 创建消息事件实例并触发事件
//        $event = new MessageEvent('你好吗？');
//        $city = new Cities();
//        $city->tigger('mine');
//        $city->save();
//        MessageEvent::trigger(MessageEvent::class,'onSendMessage');
//        die;
//        $this->behaviors['message']->sendMessage('Hello, World!');
//        die;
//        $messageEvent = new MessageEvent('Hello, World!');
//        \Yii::$app->trigger(Application::EVENT_MESSAGE, $messageEvent);
//        $this->customService->someMethod();
        // 创建事件实例并设置需要传递的数据
        /*$event       = new CustomEvent();
        $event->data = 'Some data to be processed by the behavior';
        // 触发事件
        $this->trigger('customEvent', $event);
        echo 2;
        die;*/

// 继续执行控制器的其他逻辑


        // 创建事件对象，并设置需要传递的数据
//        $event           = new CustomEvent();
//        $event->someData = 'Some data to pass to the event';
//
//        $this->trigger(CustomEvent::class, $event);
//
//        return [];
        // 触发事件，并传递事件对象

        /*// 触发UserEvent事件
        $event = new CitiesEvent();
        $event->cityId = 1001;
        $event->data = ['name' => 'John Doe'];
        $this->trigger('cityRegistered', $event);*/

        /*$query                       = Country::find();

        $pagination = new Pagination([
            'defaultPageSize' => 5,
            'totalCount'      => $query->count(),
        ]);

        $countries = $query->orderBy('name')
            ->offset($pagination->offset)
            ->limit($pagination->limit)
            ->all();

        return [
            'countries'  => $countries,
            'pagination' => $pagination,
        ];*/

        // 获取 country 表的所有行并以 name 排序
        /*$countries = Country::find()->orderBy('name')->all();

        // 获取主键为 “US” 的行
        $country = Country::findOne('US');

        // 输出 “United States”
        echo $country->name;die;

        // 参数校验
        $data['name'] = $request->get('name', '');
        $data['url']  = $request->serverName;

        Event::trigger(MyEvent::class, MyEvent::EVENT_BEFORE_VALIDATE);
        die();

        return [
            'code' => 'success',
            'data' => $data,
        ];*/
    }

    // 表单验证使用demo
    public function actionForm(Request $request)
    {
        $form           = new VenkiForm();
        $form->name     = $request->get('name', '');
        $form->email    = $request->get('email');
        $form->selected = $request->get('selected');
        $form->deleted  = $request->get('deleted');
        try {
            if ($form->validate()) {
                return $this->render('entry', ['model' => $form]);
            } else {
                return $this->render('entry-confirm', ['model' => $form]);
            }
        } catch (ErrorException $errorException) {
            Yii::error($errorException->getMessage());
        }
    }

    // 模型过滤器
    public function actionFilters(Request $request)
    {
        $params = $request->get();
        UserService::getOne($params);
    }

    // api资源
    public function actionResource(Request $request)
    {
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

        $dataProvider = new ActiveDataProvider([
            'query'      => Cities::find()->select(['id', 'updated_at', 'body', 'title'])->one(),
            'pagination' => [
                'pageSize' => 10,
            ],
        ]);

        return UserResource::collection($dataProvider->getModels());
    }

    // 队列的使用
    public function actionQueue(Request $request)
    {
        $data = $request->get();
    }

    // 模型过滤器的使用
    public function actionFilter(Request $request)
    {
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;


        $query = Books::find();
        (new BookFilter($query))->applyFilters();
        $provider = new ActiveDataProvider([
            'query' => $query,
        ]);


        $result          = [];
        $result['data']  = $provider->getModels();
        $result['total'] = $provider->getCount();
        $result['count'] = $provider->getTotalCount();

        return $result;
    }

}
